#include <iostream>
#include <cryptopp/rsa.h>       // RSA 加密、解密和签名相关类
#include <cryptopp/osrng.h>     // 随机数生成器（AutoSeededRandomPool）
#include <cryptopp/hex.h>       // 十六进制编码和解码
#include <cryptopp/filters.h>   // 数据流处理（如 StringSource 和 StringSink）
#include <cryptopp/oaep.h>      // RSA 的 OAEP 填充方案
#include <cryptopp/pssr.h>      // RSA 的 PSSR 签名方案
#include <cryptopp/eccrypto.h>  // ECC（椭圆曲线密码学）相关类
#include <cryptopp/aes.h>       // AES 加密算法
#include <cryptopp/modes.h>     // 加密模式（如 CBC、CTR 等）
#include <cryptopp/sha.h>       // SHA 哈希算法（如 SHA-256）
#include <cryptopp/cryptlib.h>  // Crypto++ 的核心库定义
#include <cryptopp/oids.h>      // ECC 曲线的 OID（如 ASN1::secp256r1）

using namespace CryptoPP;
using namespace std;

// 测试公钥加密，私钥解密
void TestPublicKeyEncryptPrivateKeyDecrypt() {
    AutoSeededRandomPool rng;

    // 生成 RSA 密钥对
    RSA::PrivateKey privateKey;
    privateKey.GenerateRandomWithKeySize(rng, 1024);
    RSA::PublicKey publicKey(privateKey);

    // 明文
    string plainText = "Hello, Crypto++!";

    // 公钥加密
    string cipherText;
    StringSource(plainText, true,
        new PK_EncryptorFilter(rng, RSAES_OAEP_SHA_Encryptor(publicKey),
            new StringSink(cipherText)
        )
    );

    // 私钥解密
    string recoveredText;
    StringSource(cipherText, true,
        new PK_DecryptorFilter(rng, RSAES_OAEP_SHA_Decryptor(privateKey),
            new StringSink(recoveredText)
        )
    );

    // 输出结果
    cout << "Test: Public Key Encrypt, Private Key Decrypt" << endl;
    cout << "Original Text: " << plainText << endl;
    cout << "Recovered Text: " << recoveredText << endl;
    cout << endl;
}

// 测试私钥签名，公钥验证
void TestPrivateKeySignPublicKeyVerify() {
    AutoSeededRandomPool rng;

    // 生成 RSA 密钥对
    RSA::PrivateKey privateKey;
    privateKey.GenerateRandomWithKeySize(rng, 1024);
    RSA::PublicKey publicKey(privateKey);

    // 消息
    string message = "This is a signed message.";

    // 私钥签名
    string signature;
    RSASS<PSSR, SHA256>::Signer signer(privateKey);
    StringSource(message, true,
        new SignerFilter(rng, signer,
            new StringSink(signature)
        )
    );

    // 公钥验证
    RSASS<PSSR, SHA256>::Verifier verifier(publicKey);
    bool result = false;
    StringSource(signature + message, true,
        new SignatureVerificationFilter(verifier,
            new ArraySink((byte*)&result, sizeof(result))
        )
    );

    // 输出结果
    cout << "Test: Private Key Sign, Public Key Verify" << endl;
    cout << "Message: " << message << endl;
    cout << "Signature Valid: " << (result ? "Yes" : "No") << endl;
    cout << endl;
}

// 测试 ECC 签名与验证
void TestECC() {
    AutoSeededRandomPool rng;

    // 生成 ECC 密钥对（使用 NIST P-256 曲线）
    ECDSA<ECP, SHA256>::PrivateKey privateKey;
    privateKey.Initialize(rng, ASN1::secp256r1());

    ECDSA<ECP, SHA256>::PublicKey publicKey;
    privateKey.MakePublicKey(publicKey);

    // 消息
    string message = "Hello, ECC!";
    string signature;

    // 签名
    ECDSA<ECP, SHA256>::Signer signer(privateKey);
    StringSource(message, true,
        new SignerFilter(rng, signer,
            new StringSink(signature)
        )
    );

    // 验证
    ECDSA<ECP, SHA256>::Verifier verifier(publicKey);
    bool result = false;
    StringSource(signature + message, true,
        new SignatureVerificationFilter(verifier,
            new ArraySink((byte*)&result, sizeof(result))
        )
    );

    // 输出结果
    cout << "Test: ECC Signature and Verification" << endl;
    cout << "Message: " << message << endl;
    cout << "Signature Valid: " << (result ? "Yes" : "No") << endl;
    cout << endl;
}

// 测试 AES 加密与解密
void TestAES() {
    AutoSeededRandomPool rng;

    // 生成随机密钥和初始化向量 (IV)
    SecByteBlock key(AES::DEFAULT_KEYLENGTH); // AES 默认密钥长度为 16 字节（128 位）
    rng.GenerateBlock(key, key.size());

    SecByteBlock iv(AES::BLOCKSIZE); // AES 块大小为 16 字节
    rng.GenerateBlock(iv, iv.size());

    // 明文
    string plainText = "Hello, AES!";
    string cipherText, recoveredText;

    // 加密
    CBC_Mode<AES>::Encryption encryption(key, key.size(), iv);
    StringSource(plainText, true,
        new StreamTransformationFilter(encryption,
            new StringSink(cipherText)
        )
    );

    // 解密
    CBC_Mode<AES>::Decryption decryption(key, key.size(), iv);
    StringSource(cipherText, true,
        new StreamTransformationFilter(decryption,
            new StringSink(recoveredText)
        )
    );

    // 输出结果
    cout << "Test: AES Encryption and Decryption" << endl;
    cout << "Original Text: " << plainText << endl;

    // 输出密文（以十六进制显示）
    string encodedCipherText;
    StringSource(cipherText, true,
        new HexEncoder(
            new StringSink(encodedCipherText)
        )
    );
    cout << "Cipher Text (Hex): " << encodedCipherText << endl;

    cout << "Recovered Text: " << recoveredText << endl;
    cout << endl;
}

// 测试 SHA-256 哈希
void TestSHA256() {
    // 消息
    string message = "Hello, SHA-256!";
    string digest;

    // 计算 SHA-256 哈希值
    SHA256 hash;
    StringSource(message, true,
        new HashFilter(hash,
            new HexEncoder(
                new StringSink(digest)
            )
        )
    );

    // 输出结果
    cout << "Test: SHA-256 Hash" << endl;
    cout << "Message: " << message << endl;
    cout << "SHA-256 Digest: " << digest << endl;
    cout << endl;
}

int main() {
    try {
        // 测试公钥加密，私钥解密
        TestPublicKeyEncryptPrivateKeyDecrypt();

        // 测试私钥签名，公钥验证
        TestPrivateKeySignPublicKeyVerify();

        // 测试 ECC 签名与验证
        TestECC();

        // 测试 AES 加密与解密
        TestAES();

        // 测试 SHA-256 哈希
        TestSHA256();
    }
    catch (const CryptoPP::Exception& e) {
        cerr << "CryptoPP Exception: " << e.what() << endl;
        return 1;
    }

    return 0;
}